package cn.com.hhrcw.service.impl;

import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.mapstruct.*;
import cn.com.hhrcw.params.EnRecruitParams;
import cn.com.hhrcw.service.*;
import cn.com.hhrcw.vo.ResumeInfoVO;
import cn.com.hhrcw.vo.SsDataInfoVO;
import cn.com.hhrcw.vo.UserInfoVo;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @program: recruit-boot-parent
 *
 * @author: JD
 * @create: 2020-11-03 15:56
 **/
@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    IPiInfoService piInfoService;

    @Autowired
    ICvResumeService resumeService;

    @Autowired
    private AdminCvResumeConvert enCvResumeConvert;

    @Autowired
    private ICvWorkIntentionService cvWorkIntentionService;

    @Autowired
    private AdminCvWorkIntentionConvert enCvWorkIntentionConvert;

    @Autowired
    private ICvUserWorkInfoService cvUserWorkInfoService;

    @Autowired
    private AdminCvUserWorkInfoConvert enCvUserWorkInfoConvert;

    @Autowired
    private ICvUserEduInfoService cvUserEduInfoService;

    @Autowired
    private AdminCvUserEduInfoConvert enCvUserEduInfoConvert;

    @Autowired
    private ICvProjectInfoService cvProjectInfoService;

    @Autowired
    private AdminCvProjectInfoConvert enCvProjectInfoConvert;

    @Autowired
    private ICvTrainService cvTrainService;

    @Autowired
    private AdminCvTrainConvert enCvTrainConvert;

    @Autowired
    private ICvLanguageLevelService cvLanguageLevelService;

    @Autowired
    private AdminCvLanguageLevelConvert enCvLanguageLevelConvert;

    @Autowired
    private ICvSkillsService cvSkillsService;

    @Autowired
    private AdminCvSkillsConvert skillsConvert;

    @Autowired
    private ICvCertificateService cvCertificateService;

    @Autowired
    private AdminCvCertificateConvert certificateConvert;

    @Autowired
    private IFileService fileService;

    @Autowired
    private IOpJobService jobService;

    @Autowired
    private AdminOpJobConvert jobConvert;

    @Autowired
    private IOpDeliveryHistoryService deliveryHistoryService;

    @Autowired
    IOpInterviewHistoryService interviewHistoryService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysUserDepartService sysUserDepartService;

    @Autowired
    private IEnRecruitService enRecruitService;

    @Autowired
    private IOpEntryHistoryService entryHistoryService;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Override
    public ResumeInfoVO getResumeInfo(String userId, Integer lanType) {
        ResumeInfoVO result = new ResumeInfoVO();
        CvResume cvResume = resumeService.lambdaQuery().eq(CvResume::getDelFlag, false).eq(CvResume::getUserId, userId).eq(CvResume::getLanType, lanType).one();
        if (cvResume == null) {
            return new ResumeInfoVO();
        }
        String resumeId = cvResume.getId();
        LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
        infoQuery.eq(PiInfo::getDelFlag, false).eq(PiInfo::getUserId, userId);
        PiInfo info = piInfoService.getOne(infoQuery);

        //个人基本信息
        UserInfoVo userInfo = new UserInfoVo();
        userInfo.setEMail(info.getEmail());
        userInfo.setLocation(info.getLiveCity());
        userInfo.setName(info.getName());
        userInfo.setSex(info.getSex());
        userInfo.setUserId(info.getUserId());
        userInfo.setWorkYears(info.getWorkYears());
        result.setUserInfo(userInfo);

        //基本信息
        result.setResumes(enCvResumeConvert.toVO(cvResume));

        //期望职位
        LambdaQueryWrapper<CvWorkIntention> workIntentionQuery = new LambdaQueryWrapper<>();
        workIntentionQuery.eq(CvWorkIntention::getDelFlag, false).eq(CvWorkIntention::getResumeId, resumeId);
        List<CvWorkIntention> workIntentions = cvWorkIntentionService.list(workIntentionQuery);
        result.setWorkIntentions(enCvWorkIntentionConvert.toVO(workIntentions));

        //工作实习经历
        LambdaQueryWrapper<CvUserWorkInfo> userWorkInfoQuery = new LambdaQueryWrapper<>();
        userWorkInfoQuery.eq(CvUserWorkInfo::getDelFlag, false).eq(CvUserWorkInfo::getResumeId, resumeId);
        List<CvUserWorkInfo> userWorkInfos = cvUserWorkInfoService.list(userWorkInfoQuery);
        result.setUserWorkInfos(enCvUserWorkInfoConvert.toVO(userWorkInfos));

        //教育经历
        LambdaQueryWrapper<CvUserEduInfo> userEduInfoQuery = new LambdaQueryWrapper<>();
        userEduInfoQuery.eq(CvUserEduInfo::getDelFlag, false).eq(CvUserEduInfo::getResumeId, resumeId);
        List<CvUserEduInfo> userEduInfos = cvUserEduInfoService.list(userEduInfoQuery);
        result.setUserEduInfos(enCvUserEduInfoConvert.toVO(userEduInfos));

        //项目经历
        LambdaQueryWrapper<CvProjectInfo> projectInfoQuery = new LambdaQueryWrapper<>();
        projectInfoQuery.eq(CvProjectInfo::getDelFlag, false).eq(CvProjectInfo::getResumeId, resumeId);
        List<CvProjectInfo> projectInfos = cvProjectInfoService.list(projectInfoQuery);
        result.setProjectInfos(enCvProjectInfoConvert.toVO(projectInfos));

        //培训经历
        LambdaQueryWrapper<CvTrain> trainQuery = new LambdaQueryWrapper<>();
        trainQuery.eq(CvTrain::getDelFlag, false).eq(CvTrain::getResumeId, resumeId);
        List<CvTrain> trainInfos = cvTrainService.list(trainQuery);
        result.setTrainInfos(enCvTrainConvert.toVO(trainInfos));

        //语言水平
        LambdaQueryWrapper<CvLanguageLevel> languageLevelQuery = new LambdaQueryWrapper<>();
        languageLevelQuery.eq(CvLanguageLevel::getDelFlag, false).eq(CvLanguageLevel::getResumeId, resumeId);
        List<CvLanguageLevel> languageLevelInfos = cvLanguageLevelService.list(languageLevelQuery);
        result.setLanguageLevelInfos(enCvLanguageLevelConvert.toVO(languageLevelInfos));

        //职业特长与技能（专业技能）
        LambdaQueryWrapper<CvSkills> skillsQuery = new LambdaQueryWrapper<>();
        skillsQuery.eq(CvSkills::getDelFlag, false).eq(CvSkills::getResumeId, resumeId);
        List<CvSkills> skillsInfos = cvSkillsService.list(skillsQuery);
        result.setSkillsInfos(skillsConvert.toVO(skillsInfos));

        //资质证书
        LambdaQueryWrapper<CvCertificate> certificateQuery = new LambdaQueryWrapper<>();
        certificateQuery.eq(CvCertificate::getDelFlag, false).eq(CvCertificate::getResumeId, resumeId);
        List<CvCertificate> certificateInfos = cvCertificateService.list(certificateQuery);
        result.setCertificateInfos(certificateConvert.toVO(certificateInfos));

        File file = fileService.getById(cvResume.getEnclosureId());
        result.setFiles(file);

        return result;
    }

    @Override
    public SsDataInfoVO getDatInfo(String ssId) {
        SsDataInfoVO result = new SsDataInfoVO();
        LambdaQueryWrapper<OpJob> jobQuery = new LambdaQueryWrapper<>();
        jobQuery.eq(OpJob::getDelFlag, false).eq(OpJob::getBsId, ssId).eq(OpJob::getBsType, 1).eq(OpJob::getRecruitmentState, 0).select(OpJob::getId);
        List<OpJob> jobs = jobService.list(jobQuery);
        if (!CollectionUtils.isEmpty(jobs)) {
            List<String> jobIds = new ArrayList<>();
            jobs.forEach(e -> {
                jobIds.add(e.getId());
            });

            //学历统计
            LambdaQueryWrapper<OpDeliveryHistory> eduQuery = new LambdaQueryWrapper<>();
            eduQuery.eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds).select(OpDeliveryHistory::getUserId, OpDeliveryHistory::getResumeId);
            List<OpDeliveryHistory> eduList = deliveryHistoryService.list(eduQuery);
            if (!CollectionUtils.isEmpty(eduList)) {
                StringBuilder sql = new StringBuilder("SELECT user_id,max(edu_level) as edu_level FROM `cv_user_edu_info` where resume_id in (");
                eduList.forEach(e -> {
                    sql.append("'" + e.getResumeId() + "',");
                });
                sql.deleteCharAt(sql.length() - 1);
                sql.append(") group by user_id");


                List<CvUserEduInfo> eduInfos = jdbcTemplate.query(sql.toString(), new BeanPropertyRowMapper<>(CvUserEduInfo.class));

                /**
                 * 最高学历 0 初中  1 高中 2 中专/中技 3 大专 4 本科 5 硕士 6 MBA/EMBA 7 博士
                 */
                int a = 7;
                int b = 5;
                int c = 6;
                int d = 3;
                int g = 4;
                int f = 2;
                if (!CollectionUtils.isEmpty(eduInfos)) {
                    eduInfos.forEach(e -> {
                        if (e.getEduLevel() != null) {
                            if (e.getEduLevel() == a) {
                                result.setDoctorCount(result.getDoctorCount() + 1);
                            } else if (e.getEduLevel() == b) {
                                result.setMasterCount(result.getMasterCount() + 1);
                            } else if (e.getEduLevel() == c) {
                                result.setMbaCount(result.getMbaCount() + 1);
                            } else if (e.getEduLevel() == d) {
                                result.setJuniorCollegeCount(result.getJuniorCollegeCount() + 1);
                            } else if (e.getEduLevel() == g) {
                                result.setUndergraduateCount(result.getUndergraduateCount() + 1);
                            } else if (e.getEduLevel() == f) {
                                result.setSecondaryCount(result.getSecondaryCount() + 1);
                            } else if (e.getEduLevel() == 1) {
                                result.setHighSchoolCount(result.getHighSchoolCount() + 1);
                            } else if (e.getEduLevel() == 0) {
                                result.setMiddleSchoolCount(result.getMiddleSchoolCount() + 1);
                            }
                        }
                    });
                }
            }
            //时间段
            Date todayZero = new Date();
            long zero = cn.com.hhrcw.utils.DateUtil.getTodayZero();
            //今天凌晨
            todayZero.setTime(zero);
            Date lastDayZero = new Date();
            lastDayZero.setTime(zero - 86400000);

            LambdaQueryWrapper<OpDeliveryHistory> todayQuery = new LambdaQueryWrapper<>();
            todayQuery.eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds).ge(OpDeliveryHistory::getCreateTime, todayZero);
            List<OpDeliveryHistory> today = deliveryHistoryService.list(todayQuery);
            /** 数据统计
             * 0 未阅读 1 已阅读  2 不合适 3 通过筛选 4  面试 5已发offer(已录用)6 已入职 7 被过滤
             */

            int historiesToday = interviewHistoryService.lambdaQuery().in(OpInterviewHistory::getJobId, jobIds).ge(OpInterviewHistory::getCreateTime, todayZero).count();
            result.setViewCountToday(historiesToday);

            int offerCountToday = entryHistoryService.lambdaQuery().in(OpEntryHistory::getJobId, jobIds).ge(OpEntryHistory::getCreateTime, todayZero).count();
            result.setUseCountToday(offerCountToday);

            if (!CollectionUtils.isEmpty(today)) {
                result.setDeliveryCountToday(today.size());
                today.forEach(e -> {
                    if (e.getState() != null) {
                        int a =6;
                        if (a == e.getState()) {
                            result.setEntryCountToday(result.getEntryCountToday() + 1);
                        }
                    }
                });
            }

            //昨日
            LambdaQueryWrapper<OpDeliveryHistory> lastDayQuery = new LambdaQueryWrapper<>();
            lastDayQuery.eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds).ge(OpDeliveryHistory::getCreateTime, lastDayZero).lt(OpDeliveryHistory::getCreateTime, todayZero);
            List<OpDeliveryHistory> lastDay = deliveryHistoryService.list(lastDayQuery);
            int historiesLastDay = interviewHistoryService.lambdaQuery().in(OpInterviewHistory::getJobId, jobIds).ge(OpInterviewHistory::getCreateTime, lastDayZero).lt(OpInterviewHistory::getCreateTime, todayZero).count();
            result.setViewCountLastDay(historiesLastDay);

            int offerCount = entryHistoryService.lambdaQuery().in(OpEntryHistory::getJobId, jobIds).ge(OpEntryHistory::getCreateTime, lastDayZero).lt(OpEntryHistory::getCreateTime, todayZero).count();
            result.setUseCountLastDay(offerCount);
            if (!CollectionUtils.isEmpty(lastDay)) {
                result.setDeliveryCountLastDay(lastDay.size());
                today.forEach(e -> {
                    //0 未阅读  1 已阅读 2 不合适 3通过筛选4 面试 5已发offer(已录用) 6 已入职 7 被系统过滤 8未入职9反馈面试结果(通过)10反馈面试结果(不通过)
                    if (e.getState() != null) {
                        int a = 6;
                        if (a == e.getState()) {
                            result.setEntryCountLastDay(result.getEntryCountLastDay() + 1);
                        }
                    }
                });
            }


        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addColleague(EnRecruitParams params) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        boolean saved = false;
        SysUser userState = sysUserService.lambdaQuery()
                .eq(SysUser::getPhone, params.getPhone())
                .eq(SysUser::getDelFlag, false)
                .one();
        if (userState == null) {
            SysUser user = new SysUser();
            String salt = oConvertUtils.randomGen(8);
            String passwordEncode = PasswordUtil.encrypt(params.getPhone(), salt, salt);
            user.setCreateBy(sysUser.getId());
            user.setCreateTime(DateUtil.date());
            user.setDelFlag(false);
            user.setSalt(salt);
            user.setUsername(params.getPhone());
            user.setRealname(params.getUserName());
            user.setPassword(passwordEncode);
            user.setEmail(params.getMailbox());
            user.setPhone(params.getPhone());
            user.setCreateTime(DateUtil.date());
            saved = sysUserService.save(user);

            SysUserDepart sysUserDepart = new SysUserDepart();
            sysUserDepart.setUserId(user.getId());
            sysUserDepart.setDepId(params.getCompanyId());
            sysUserDepartService.save(sysUserDepart);

            PiInfo piInfo = new PiInfo();
            piInfo.setCreateBy(sysUser.getId());
            piInfo.setCreateTime(DateUtil.date());
            piInfo.setDelFlag(false);
            piInfo.setUserId(user.getId());
            piInfo.setRoleType("1");
            piInfo.setPhone(params.getPhone());
            piInfo.setName(params.getUserName());
            piInfo.setEmail(params.getMailbox());
            piInfoService.save(piInfo);

            EnRecruit recruit = new EnRecruit();
            recruit.setCreateBy(sysUser.getId());
            recruit.setCreateTime(DateUtil.date());
            recruit.setDelFlag(false);
            recruit.setUserId(user.getId());
            recruit.setUserName(params.getUserName());
            recruit.setNickName(params.getNickName());
            recruit.setJob(params.getJob());
            recruit.setDepart(params.getDepart());
            recruit.setPhone(params.getPhone());
            recruit.setMailbox(params.getMailbox());
            enRecruitService.save(recruit);
        } else {
            PiInfo piInfoState = piInfoService.lambdaQuery()
                    .eq(PiInfo::getUserId, userState.getId())
                    .eq(PiInfo::getDelFlag, false)
                    .one();
            String a = "1";
            if (piInfoState.getRoleType().contains(a)) {
                return Result.error("添加失败，对方已加入企业");
            } else {
                SysUserDepart sysUserDepart = new SysUserDepart();
                sysUserDepart.setUserId(userState.getId());
                sysUserDepart.setDepId(params.getCompanyId());
                saved = sysUserDepartService.save(sysUserDepart);

                String type = piInfoState.getRoleType();
                if (StringUtils.isEmpty(type)) {
                    type += "1";
                } else {
                    type += ",1";
                }
                LambdaUpdateWrapper<PiInfo> piUpdateWrapper = Wrappers.lambdaUpdate();
                piUpdateWrapper.in(PiInfo::getUserId, userState.getId())
                        .eq(PiInfo::getDelFlag, false)
                        .set(PiInfo::getPhotoId, params.getPhotoId())
                        .set(PiInfo::getName, params.getUserName())
                        .set(PiInfo::getPhone, params.getPhone())
                        .set(PiInfo::getEmail, params.getMailbox())
                        .set(PiInfo::getRoleType, type)
                        .set(PiInfo::getUpdateBy, sysUser.getUsername())
                        .set(PiInfo::getUpdateTime, DateUtil.date());
                piInfoService.update(piUpdateWrapper);

                EnRecruit recruit = enRecruitService
                        .lambdaQuery()
                        .eq(EnRecruit::getUserId, userState.getId())
                        .eq(EnRecruit::getDelFlag, false)
                        .one();
                if (recruit == null) {
                    recruit = new EnRecruit();
                    recruit.setCreateBy(sysUser.getId());
                    recruit.setCreateTime(DateUtil.date());
                    recruit.setDelFlag(false);
                    recruit.setUserId(userState.getId());
                    recruit.setUserName(params.getUserName());
                    recruit.setNickName(params.getNickName());
                    recruit.setJob(params.getJob());
                    recruit.setDepart(params.getDepart());
                    recruit.setPhone(params.getPhone());
                    recruit.setMailbox(params.getMailbox());
                    enRecruitService.save(recruit);
                } else {
                    LambdaUpdateWrapper<EnRecruit> updateWrapper = Wrappers.lambdaUpdate();
                    updateWrapper.in(EnRecruit::getUserId, userState.getId())
                            .eq(EnRecruit::getDelFlag, false)
                            .set(EnRecruit::getUserName, params.getUserName())
                            .set(EnRecruit::getNickName, params.getNickName())
                            .set(EnRecruit::getJob, params.getJob())
                            .set(EnRecruit::getDepart, params.getDepart())
                            .set(EnRecruit::getPhone, params.getPhone())
                            .set(EnRecruit::getMailbox, params.getMailbox())
                            .set(EnRecruit::getUpdateBy, sysUser.getUsername())
                            .set(EnRecruit::getUpdateTime, DateUtil.date());
                    enRecruitService.update(updateWrapper);
                }

            }
        }
        return saved ? Result.ok() : Result.error("添加失败");
    }
}
